package com.sunwayworld.basemodule.business.ordertask.service.impl;

import com.sunwayworld.basemodule.business.ordertask.bean.LimsOrderTaskBean;
import com.sunwayworld.basemodule.business.ordertask.bean.LimsRunBoardHoleBean;
import com.sunwayworld.basemodule.business.ordertask.service.LimsOrderTaskService;
import com.sunwayworld.basemodule.business.ordertask.service.LimsRunBoardHoleService;
import com.sunwayworld.basemodule.business.result.bean.LimsRunBean;
import com.sunwayworld.basemodule.business.result.service.LimsRunService;
import com.sunwayworld.basemodule.common.constant.LimsConstant;
import com.sunwayworld.framework.database.sql.Order;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.utils.ArrayUtils;
import com.sunwayworld.framework.utils.NumberUtils;
import com.sunwayworld.framework.utils.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;


import com.sunwayworld.basemodule.business.ordertask.service.LimsRunBoardService;
import com.sunwayworld.framework.restful.data.RestJsonWrapperBean;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Repository
public class LimsRunBoardServiceImpl implements LimsRunBoardService {

    @Autowired
    @Lazy
    private LimsRunService runService;

    @Autowired
    @Lazy
    private LimsRunBoardHoleService runBoardHoleService;

    @Autowired
    @Lazy
    private LimsOrderTaskService orderTaskService;

    @Override
    @Transactional
    public String updateSampleLocations(RestJsonWrapperBean wrapper) {
        List<LimsRunBean> boardBeans = wrapper.parse(LimsRunBean.class, 0);// 板
        List<LimsOrderTaskBean> parses = wrapper.parse(LimsOrderTaskBean.class, 1);//
        List<Long> orderTaskIds = parses.stream().filter(s -> ObjectUtils.isEmpty(s.getBoardHoleId())).map(LimsOrderTaskBean::getId).distinct()
                .collect(Collectors.toList());  // 跳过已经分配的

        List<LimsOrderTaskBean> orderTaskBeans = orderTaskService.selectListByFilter(SearchFilter.instance().match("id",orderTaskIds).filter(MatchPattern.OR), Order.desc("sampleCode"));

        // 通过选中的位置，找到位置下的孔，顺序分配孔位
        List<Long> ids = boardBeans.stream().map(LimsRunBean::getId).collect(Collectors.toList());
        String assignType = wrapper.getParamValue("assignType");
        // 获取起始孔位
        int row = NumberUtils.parseInt(wrapper.getParamValue("row"));// 行表示y轴
        int col = NumberUtils.parseInt(wrapper.getParamValue("col"));// 列表示x轴
//        String start
        List<LimsRunBoardHoleBean> holeBeans;
        if("y".equalsIgnoreCase(assignType)){ // 竖着排
            holeBeans = runBoardHoleService.selectListByFilter(SearchFilter.instance()
                            .match("boardId", ids).filter(MatchPattern.OR)
                            .match("stockType", "free").filter(MatchPattern.EQ)
                    , Order.asc("x"), Order.asc("y"));
            // 判断可分配的孔位是否足够
            if (holeBeans.size() < orderTaskBeans.size()) {
                return "库位不足";
            }
            // 纵向排列时，排除孔位（x坐标小于起始x坐标、x坐标相等y坐标小于起始y坐标）
            holeBeans.removeIf(e -> (e.getX() < col) || (e.getX() == col && e.getY() < row));
        } else { // 横着排
            holeBeans = runBoardHoleService.selectListByFilter(SearchFilter.instance()
                            .match("boardId", ids).filter(MatchPattern.OR)
                            .match("stockType", "free").filter(MatchPattern.EQ)
                    , Order.asc("y"), Order.asc("x"));
            // 判断可分配的孔位是否足够
            if (holeBeans.size() < orderTaskBeans.size()) {
                return "库位不足";
            }
            // 横向排列时，排除孔位（y坐标小于起始y坐标、y坐标相等x坐标小于起始x坐标）
            holeBeans.removeIf(e -> (e.getY() < row) || (e.getY() == row && e.getX() < col));
        }
        // 判断可分配的孔位是否足够
        if (holeBeans.size() < orderTaskBeans.size()) {
            return "库位不足";
        }

        List<LimsOrderTaskBean> updateSampleBeans = new ArrayList<>();
        List<LimsRunBoardHoleBean> updateLocationHoleBeans = new ArrayList<>();

        // 给每个样本 分配孔位
        for (int i = 0; i < orderTaskBeans.size(); i++) {
            LimsOrderTaskBean orderTaskBean = orderTaskBeans.get(i);

            LimsRunBoardHoleBean holeBean = holeBeans.get(i);
            holeBean.setOrderTaskId(orderTaskBean.getId());
            holeBean.setStockType("in");
            if ("0".equals(orderTaskBean.getExt$Item("qcsampleflg"))){ // 实验样本
                holeBean.setSampleFlag("0");
            }else{
                holeBean.setSampleFlag("1");
            }
            updateLocationHoleBeans.add(holeBean);
            LimsRunBean runBean = boardBeans.get(0);
            orderTaskBean.setBoardHoleId(holeBean.getId());
            // 增加到批
            orderTaskBean.setAddInRun("1");
            orderTaskBean.setRunCode(runBean.getRunCode());
            orderTaskBean.setRunId(runBean.getId());
            orderTaskBean.setMethodCode(runBean.getMethodCode());
            orderTaskBean.setMethodDesc(runBean.getMethodDesc());
            orderTaskBean.setTesterId(runBean.getAnalystId());
            orderTaskBean.setTester(runBean.getAnalystName());
            orderTaskBean.setReviewer(runBean.getReviewer());
            orderTaskBean.setReviewerId(runBean.getReviewerId());
            orderTaskBean.setTestMethodId(runBean.getTestMethodId());
            updateSampleBeans.add(orderTaskBean);

        }
        orderTaskService.getDao().update(updateSampleBeans, ArrayUtils.asList( "runCode","runId","addInRun","boardHoleId", "methodCode", "methodDesc", "testerId", "tester", "reviewer", "reviewerId", "testMethodId"));
        runBoardHoleService.getDao().update(updateLocationHoleBeans, "orderTaskId", "stockType","sampleFlag");
        return "success";
    }

    @Override
    @Transactional
    public void clearSampleHole(RestJsonWrapperBean wrapper) {
        LimsRunBoardHoleBean holeBean = wrapper.parseUnique(LimsRunBoardHoleBean.class);
        LimsOrderTaskBean orderTaskBean = new LimsOrderTaskBean();
        orderTaskBean.setId(holeBean.getOrderTaskId());
        orderTaskBean.setRunId(null);
        orderTaskBean.setRunCode(null);
        orderTaskBean.setAddInRun("0");
        orderTaskService.getDao().update(orderTaskBean,"boardHoleId","runCode","runId","addInRun");
        holeBean.setSampleFlag(null);
        holeBean.setOrderTaskId(null);
        holeBean.setStockType(LimsConstant.HOLE_STOCKTYPE_FREE);
        runBoardHoleService.getDao().update(holeBean,"orderTaskId", "stockType","sampleFlag");
    }

    @Override
    @Transactional
    public void updateSampleBoardHole(RestJsonWrapperBean wrapper) {
        LimsRunBoardHoleBean holeBean = wrapper.parseUnique(LimsRunBoardHoleBean.class);

        Long orderTaskId = holeBean.getOrderTaskId();
        if(orderTaskId == null){
            return;
        }
        LimsOrderTaskBean orderTaskBean = orderTaskService.selectByIdIfPresent(orderTaskId);

        if(orderTaskBean != null){
            List<LimsRunBoardHoleBean> updates = new ArrayList<>();
            if(orderTaskBean.getBoardHoleId() != null){ // 原板
                LimsRunBoardHoleBean boardHoleBean = runBoardHoleService.selectById(orderTaskBean.getBoardHoleId());
                boardHoleBean.setOrderTaskId(null);
                boardHoleBean.setSampleFlag(null);
                boardHoleBean.setStockType(LimsConstant.HOLE_STOCKTYPE_FREE);
                updates.add(boardHoleBean);
            }

            orderTaskBean.setBoardHoleId(holeBean.getId());
            // 增添到批
            orderTaskBean.setRunId(holeBean.getBoardId());
            LimsRunBean runBean = runService.getDao().selectById(holeBean.getBoardId());
            orderTaskBean.setAddInRun("1");
            orderTaskBean.setRunCode(runBean.getRunCode());
            orderTaskService.getDao().update(orderTaskBean, ArrayUtils.asList("runCode","addInRun","runId", "boardHoleId"));
            if ("0".equals(holeBean.getSampleFlag())){ // 实验样本
                holeBean.setSampleFlag("0");
            }else{
                holeBean.setSampleFlag("1");
            }
            holeBean.setStockType(LimsConstant.HOLE_STOCKTYPE_IN);
            updates.add(holeBean);
            runBoardHoleService.getDao().update(updates, "orderTaskId", "stockType","sampleFlag");
        }
    }
}
